﻿#include <Windows.h>
#include <WinUser.h>
#include <windef.h>
#include <WinBase.h>
#include <time.h>
#include <assert.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <tchar.h>

#include "Vector.h"
#include "Matrix.h"
#include "Screen.h"
#include "Device.h"
#include "config.h"
#include "Color.h"
#include "Transform.h"
#include "Light.h"
#include "Vertex.h"
#include "Model.h"

extern _Color _color;

Screen* screen = NULL;
Device* device = NULL;
Transform *transform = NULL;

void InitConsoleWindow()
{
	if (AllocConsole()) {
		freopen("CONOUT$", "w", stdout);
	}
}

void drawLine2D() {
	Vector v0(60, 60, 0, 1);
	Vector v1(100, 360, 0, 1);
	device->drawLine2D(v0, v1, _color.RED);
}
void drawLine3D() {
	Vector v0(0, 0, 0, 1);
	Vector v1(4, 0, 0, 1);
	device->drawLine3D(v0, v1, _color.RED);

	Vector v2(0, 4, 0, 1);
	device->drawLine3D(v0, v2, _color.BLUE);

	Vector v3(0, 0, 4, 1);
	device->drawLine3D(v0, v3, _color.GREEN);
}
//画3D三角形线框
void drawTriangleWireframe() {
	Vector v0(-1, 0, 2, 1);
	Vector v1(1, 0, 2, 1);
	Vector v2(0, 0, 1, 1);

	device->drawTriangleWireframe(v0, v1, v2);
}
void drawTrangleFill() {
	Vector v0(-1, 0, 2, 1);
	Vector v1(1, 1, 0, 1);
	Vector v2(0, 2, 1, 1);

	device->drawTriangleFill(v0, v1, v2);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd) {
	InitConsoleWindow();
	srand((unsigned)time(NULL));

	screen = new Screen();
	int ret = screen->init(WINDOW_WIDTH, WINDOW_HEIGHT, _T("SoftRendering"));
	if (ret < 0) {
		printf("screen init failed(%d)!\n", ret);
		exit(ret);
	}

	transform = new Transform();
	transform->init();

	device = new Device();
	device->init(WINDOW_WIDTH, WINDOW_HEIGHT, (uint32*)(screen->getFrameBuffer()), transform);

	Model model("model/teapot.obj", device);

	Vector eye(0, 0, 10);
	transform->setView(eye);
	Matrix tem;
	tem.setRotate(1, 0, 0, PI);
	transform->setWorld(tem);
	Matrix setWorldRotate;
	setWorldRotate.setRotate(0, 1, 0, PI / 200);

	float theta = 1;

	while (!screen->isExit()) {
		device->clear();
		screen->dispatch();
		//TODO:setCamera
		transform->changeWorld(setWorldRotate);

		//TODO:clear ZBuffer
			//在device clear中完成

		//TODO:Test
			//drawLine2D();
		drawLine3D();
			//drawTriangleWireframe();
			//drawTrangleFill();
		model.Draw();
		
		screen->dispatch();
		screen->update();
		Sleep(1);
	}
	return 0;
}